﻿namespace MyAppAPI.Utils.LinqExtend
{
    public class LinqExtensions
    {
        private static void Sample01()
        {
            var stock = new Stock { Name = "Stock Demo" };
            stock.Quotes = new List<Quote>
            {
                new Quote{Stock = stock, Price = 200, Date = DateTime.Parse("2020/3/29")},
                new Quote{Stock = stock, Price = 150, Date = DateTime.Parse("2020/3/21")},
                new Quote{Stock = stock, Price = 220, Date = DateTime.Parse("2020/3/23")},
                new Quote{Stock = stock, Price = 180, Date = DateTime.Parse("2020/3/25")},
                new Quote{Stock = stock, Price = 100, Date = DateTime.Parse("2020/3/26")},
            };
            Console.WriteLine($"Stock: {stock}");

            var minQuote = stock.Quotes.MinItem(q => q.Date);


            Console.WriteLine(minQuote.Price);
        }
        private static void Sample02()
        {
            var customers = new List<Customer>
            {
                new Customer{Name = "张三", Age = 20, Visible = false},
                new Customer{Name = "李四", Age = 18},
                new Customer{Name = "王五", Age = 22},
            };

            var query = from c in customers
                        where c.Age < 22
                        select c;

            foreach (var customer in query)
            {
                Console.WriteLine(customer);
            }
        }
        //mapreduce
        public static void Sample05()
        {
            var words = File.ReadAllText("Data.txt").Split(' ');
            var map = words.AsParallel().ToLookup(p => p, k => 1);
            var reduce = from IGrouping<string, int> wordMap in map.AsParallel()
                         where wordMap.Count() > 1
                         select new { Word = wordMap.Key, Count = wordMap.Count() };

            foreach (var word in reduce)
            {
                Console.WriteLine($"Word: {word.Word},Count:{word.Count}");
            }
        }
    }
    public interface IVisible
    {
        bool Visible { get; set; }
    }
    public class Customer : IVisible
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public bool Visible { get; set; }

        public Customer()
        {
            Visible = true;
        }

        public override string ToString()
        {
            return $"{Name} 今年 {Age} 岁了";
        }
    }
    public class Quote
    {
        public Stock Stock { get; set; }
        public decimal Price { get; set; }
        public DateTime Date { get; set; }
    }

    public class Stock
    {
        public string Name { get; set; }
        public List<Quote> Quotes { get; set; }
        public override string ToString()
        {
            return $"{Name}: MIN {Quotes.Min(q => q.Price)} - MAX {Quotes.Max(q => q.Price)}";
        }
    }
    public static class Extensions
    {
        public static Quote MinPrice(this IEnumerable<Quote> source)
        {
            return source.Aggregate((t, s) => t.Price < s.Price ? t : s);
        }

        public static TSouce MinItem<TSouce, TCompareValue>(this IEnumerable<TSouce> source,
            Func<TSouce, TCompareValue> comparerExpression)
        {
            var comparer = Comparer<TCompareValue>.Default;
            return source.Aggregate((minValue, item) =>
            {

                var result = comparer.Compare(comparerExpression(minValue), comparerExpression(item));
                return result < 0 ? minValue : item;
            });
        }
        //特化现有操作符
        public static IEnumerable<TSource> Where<TSource>(
            this IEnumerable<TSource> source,
            Func<TSource, bool> predicate) where TSource : IVisible
        {
            return Enumerable.Where(source, item => item.Visible == true && predicate(item));
        }
    }
}
